package com.achievo.reportserver.servlet;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;

import com.achievo.reportserver.ReportConfigProcessor;
import com.achievo.reportserver.ReportDomUtils;
import com.achievo.reportserver.ReportFacade;
import com.achievo.reportserver.config.ConfigFactory;
import com.achievo.reportserver.config.ReportConfigStore;
import com.achievo.reportserver.config.ReportDef;

/**
 * 
 * Report Server
 * write at Jan 21, 2010
 * @author <a href="mailto:chinaoryx@gmail.com">Hyman.Zhang (Zhang Haipeng)</a>
 * @version 1.0
 * 
 *
 */
public class ReportPrintServlet extends HttpServlet {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(ReportPrintServlet.class);

	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ReportPrintServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Writer writer = response.getWriter();
		String reportId = request.getParameter("_REPORTID");
		String[] emails = request.getParameterValues("_EMAIL");

		Map params = request.getParameterMap();
		ReportDef reportDef = ReportConfigStore.getReport(reportId);

		String outFileRoot = ConfigFactory.getServerConfig().getString("reportOutputRoot");

		ReportConfigProcessor configProcessor = new ReportConfigProcessor();

		String schema = request.getScheme();
		String host = request.getServerName();
		String patchInfo = request.getPathInfo();
		StringBuffer urlxx = request.getRequestURL();
		String servletPath = request.getServletPath();
		String contextPath = request.getContextPath();
		int port = request.getServerPort();
		StringBuffer serverLoc = new StringBuffer(schema);
		serverLoc.append("://");
		serverLoc.append(host);
		serverLoc.append(":");
		serverLoc.append(port);

		if (!StringUtils.isEmpty(contextPath)) {
			serverLoc.append(contextPath);
		}
		serverLoc.append("/");
		// serverLoc.append("aaaaa");

		// serverLoc.append("ReportDownload?");
		 String outRoot =
		 ConfigFactory.getServerConfig().getString("reportOutputRoot");
		serverLoc.append(outFileRoot);
		serverLoc.append("/");

//		String servletRealPath = request.getSession().getServletContext().getRealPath("");
//		if (!servletRealPath.endsWith(File.separator)) {
//			servletRealPath = servletRealPath + File.separator;
//		}
		String realPath = ConfigFactory.SERVER_REAL_PATH + outFileRoot + File.separator;

		// ReportDef newReportDef = null;
		try {
			reportDef = configProcessor.reBuildDef(params, reportDef);
		} catch (Exception e2) {
			throw new ServletException(e2);
		}
		reportDef.setOutFileRealPathRoot(realPath);
		reportDef.setOutFileServerPathRoot(serverLoc.toString());
		reportDef.setMailList(Arrays.asList(emails));

		logger.info(reportDef);

		// print..
		ReportFacade facade = new ReportFacade(reportDef);
		Throwable t = null;
		try {
			if (BooleanUtils.toBoolean(reportDef.getIsSync())) {
				facade.printReport();
			} else {
				Thread thread = null;
				thread = new Thread(facade);
				thread.start();
			}
		} catch (Exception e1) {
			logger.error("printReport Error!", e1);
			t = e1;
		}

		ReportDomUtils domUtil = new ReportDomUtils();
		String errorDesc = null;
		String status = "OK";
		if (t != null) {
			status = "ERROR";
			errorDesc = domUtil.stringThrowable(t);
		}

		try {
			domUtil.fillResponseDoc(writer, reportDef, status, errorDesc);
		} catch (DocumentException e) {
			throw new IOException(e);
		}

		writer.close();

	}

	// private void fillResponseDoc(Writer writer, ReportDef reportDef,
	// ReportDomUtils domUtil, String errorDesc,
	// String status) throws IOException {
	// Document doc = null;
	// ClassLoader classloader = this.getClass().getClassLoader();
	// URL url = classloader.getResource("xmltemplate/response_reportinfo.xml");
	// try {
	// doc = domUtil.parse(url);
	// } catch (DocumentException e) {
	// logger.error("Parse file xmltemplate/response_reportinfo.xml error!", e);
	// e.printStackTrace();
	// }
	//		
	// Node statusNode = doc.selectSingleNode(
	// "//reportResponse/responseHead/status" );
	// Node descNode = doc.selectSingleNode(
	// "//reportResponse/responseHead/desc" );
	// statusNode.setText(status);
	// descNode.setText(errorDesc);
	//		
	// domUtil.fillReportDef(reportDef, doc);
	// doc.write(writer);
	// }

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		this.doGet(request, response);
	}

}
